#pragma once

#include <vector>
#include <sys/epoll.h>

namespace GiSo {

class Channel; // 前置声明，避免循环依赖

using ChannelList = std::vector<Channel*>;

class Poller {
public:
    /**
     * @brief Poller 类的构造函数.
     *
     * 创建 epoll 实例. 如果创建失败，会打印错误信息.
     */
    Poller();

    /**
     * @brief Poller 类的析构函数.
     *
     * 关闭 epoll 文件描述符.
     */
    ~Poller();

    /**
     * @brief 执行事件轮询，监听文件描述符上的事件.
     *
     * @param timeoutMs 超时时间，单位毫秒. -1 表示无限等待.
     * @param activeChannels 输出参数，用于返回活跃的 Channel 列表.
     * @return 发生事件的文件描述符的数量.
     *         返回值大于 0 表示有事件发生，等于 0 表示超时，小于 0 表示出错.
     */
    int Poll(int timeoutMs, ChannelList& activeChannels);

    /**
     * @brief 更新 Channel 关注的事件.
     *
     * 如果 Channel 尚未被 Poller 监听，则添加监听.
     * 如果 Channel 已经在监听，则修改监听的事件类型.
     *
     * @param channel 要更新的 Channel 对象指针.
     */
    void UpdateChannel(Channel* channel);

    /**
     * @brief 移除对 Channel 的事件监听.
     *
     * 当 Channel 不再需要被 Poller 监听时调用.
     *
     * @param channel 要移除监听的 Channel 对象指针.
     */
    void RemoveChannel(Channel* channel);

private:
    using EventList = std::vector<epoll_event>;

    int m_Epfd;          ///< epoll 文件描述符
    EventList m_Events;   ///< 用于接收 epoll_wait 返回的事件数组

    static const int s_PollTimeMs = 10000; ///< 默认 poll 超时时间 (10 秒)
};

}